<?php
/**
 * Higher level of database access abstraction. The data are manipulated as
 * arrays becouse PHP objects are not effective enough.
 *
 * @author Martin "DevelX" Jurča
 * @version 2009-01-24
 */
interface DBAPI {
     /**
     * Initializates DB API with specified driver.
     *
     * @param DBDriver $driver The database driver that will handle the lower
     *        layer of database access abstraction.
     * @throws Exception When driver is null.
     */
    public function __construct(DBDriver $driver);

    /**
     * Loads records from the database that fits specified conditions.
     * When no records fits the given conditions, method returns an empty
     * array. Event "load" is invoked on all loaded records.
     *
     * @param Array $dataModel Data schema of record to load. This schema
     *        has all necessary information (table name, columns specification)
     *        but no data.
     * @param String $condition For more details see the delete method in DB
     *        Driver interface. This paramter is optional and when ommited or
     *        set to an empty array, function returns all records of specified
     *        type.
     * @param Array $orderBy Array of properties names stored in database. The
     *        returned objects will be ordered by values in these properties.
     *        Default ordering is ascendent, for descendent ordering insert
     *        exclamation mark in front of the property name (e.g.: !id).
     * @param int $limitFrom For more details see the DBDriver interface,
     *        method select. This parameter is optional.
     * @param int $limitCount For more details see the DBDriver interface,
     *        method select. This parameter is optional.
     * @return Array Records ordered in specified way. When error occures, the
     *        method returns false.
     */
    public function &load(&$dataModel, $conditions = '', &$orderBy = array(),
            $limitFrom = 0, $limitCount = -1);

    /**
     * Saves all data of the record to the database. This method should be used
     * only when inserting new record with new ids. Before writing the data to
     * database method invokes 'save' event.
     *
     * @param Array $record For more details see the refresh method.
     * @return boolean True on success, false otherwise.
     */
    public function save(&$record);

    /**
     * Updates data of the record in the database by the data of given record.
     * Also invokes 'update' event on object before putting the data to the
     * database.
     *
     * @param Array $record For more details see the refresh method.
     * @param Array $properties List of properties to be updated in the
     *        database. When omited or set to empty array, all properties are
     *        updated.
     * @return boolean True on success, false otherwise.
     */
    public function update(&$record, &$properties = array());

    /**
     * Deletes record from the database. This method can be applyied to a
     * record of which at least one property is primary key or unique in
     * database table and has no side effect to any other record.
     *
     * @param Array $record Record in form specified in refresh method.
     * @return boolean True on success, false otherwise.
     */
    public function delete(&$record);

    /**
     * Reloads data of the record from the database refreshing the cache and
     * recalculates specific properties of the record, also 'refresh' event is
     * invoked after the data is reloded.
     *
     * @param Array $record Multidimensional array representing all data
     *        describing the database record and related data. The structure
     *        is:
     *            <object> := [<table>, <properties>, <data>]
     *        <properties> is an array indexed by column names. Values of this
     *        array descibes column data type. To see the data type
     *        specification, see the DB Driver interface specification, the
     *        alterTable method. However, the are also some special data
     *        types:
     *            r<relation> - represents relation data type. Relationship
     *                          between this data and the others is expressed
     *                          by a mathematical formula that constist of
     *                          operators, e.g.: + - * / ( ), or numeric
     *                          constants, e.g: 532, 43.11, or names of other
     *                          columns. Each time the load or refresh
     *                          method is invoked on record, these properties
     *                          are recalculated. When column is of this type,
     *                          no other details may be specified.
     *             e<command> - event-type data. Event could be invoked on
     *                          object using DB API to perform some basic
     *                          calculations, e.g. increasing the counter,
     *                          etc. Command is specified by an event name and
     *                          the operation that will be performed on the
     *                          data. Event-type data are like relation data
     *                          stored only in memory and performs operations
     *                          on the data loaded from the database. Syntax
     *                          of  event data is following:
     *                               <command> := <event name>:<operation>
     *                             <operation> := inc(<column>) |
     *                                            dec(<column>) |
     *                                            null(<column>) |
     *                                            set(<column>,<relation>) |
     *                                            func(<column>,<php function>)
     *                          When using the func operation, php function is
     *                          represented by it's name. This function should
     *                          return single value - string or a number. This
     *                          value will be saved to specified column.
     *                          Example: eload:inc(loaded)
     *                <array> - Linked record. Use this to add list of
     *                          another records to this record.
     *                          Field are: ['linkBy' = <link-by>,
     *                                      'linkTo' => <link-to>,
     *                                      'linkOp' => <link-operator>,
     *                                      'record' => <record data schema>]
     *                          To load only records that are really
     *                          connected with this one, relation between them
     *                          should be specified using <link-by> column name
     *                          and <link-to> column name. <link-by> is column
     *                          name of attached record(s). <link-to> specifies
     *                          name of the column of this record.
     *                          Only record(s) whose match condition
     *                          <link-to> <link-operator> <link-by> are
     *                          attached to this record. Since this relation
     *                          may be recursive, it is simple way of creating
     *                          whole category trees, etc. Allowed operators
     *                          are =, !=, >, <, >=, <=
     *        <data> is an array indexed by column names. Values represents
     *        values of data loaded from the database or calculated.
     *        As $record is in fact only array instead of real PHP object,
     *        lower usage of memory and better performance is provided.
     * @return boolean True on success, false otherwise.
     */
    public function refresh(&$record);

    /**
     * Invokes an event on given object and performs specified operations.
     * Command that can be executed by event are:
     * inc(column) : increments value of the column
     * dec(column) : decrements value of the column
     * null(column) : sets value of the column to 0
     * set(column,relation) : evaluates relation upon data of the record and
     *                        sets the result to the column.
     * func(column,function) : Executes php function of given name. The
     *                         function recieves as the only argument the data
     *                         of the record and the result is then set as the
     *                         value of the column.
     *
     * @param Array $record For more details see the refresh method.
     * @param String $event Name of event to be invoked on record, e.g.
     *        update.
     */
    public function invokeEvent(&$record, $event);

    /**
     * Returns database access driver object.
     *
     * @return DBDriver The database access driver object.
     */
    public function getDriver();
}
?>
